还是老样子不写网上可以搜索到的基础知识,写比较关键的实际应用比较实用的东西。
本篇文章中说到的所有东西都是对Cypress PSOC1芯片基础上实现SPI液晶驱动的总结。
SPI通讯时序几个模式的区别
开始的时候总是对SPI通信时序的Mode 0,1,2,3分不清楚。
CPOL:时钟极性,
CPOL=0:空闲时SCK为低电平,第一个SCK脉冲由上升沿开始
CPOL=1:空闲时SCK为高电平,第一个SCK脉冲由下降沿开始CPHA:时钟相位,
CPHA=0:第一个跳变沿采集数据,也就是说未开始之前,第一个数据已经准备好,第一个跳变沿就直接开始采集
CPHA=1:第二个跳变沿采集数据,也就是说未开始之前,第一个数据可以没准备,可以在第一个SCK跳变沿准备,第二个采集
例子
举个实际例子,就是液晶屏SPI通信时的一段最基本的通信代码,使用IO引脚软件模拟SPI时序:1
2
3
4
5
6
7
8
9
10
11
12for(i = 0; i<8; i++) //8位数据, 先高后低
{
if(wbyte & 0x80) {LCD_DIN_HIGH;}
else {LCD_DIN_LOW;}
wbyte <<= 1; //移位(延时)
for(j=0;j<10;j++);
LCD_CLK_HIGH; //上升沿写入
for(j=0;j<10;j++);
LCD_CLK_LOW ;
for(j=0;j<10;j++);
}
分析下,首先根据要传送的一个字节数据,准备好了电平,然后给上升沿,然后再下降沿,
初始化的时候,SCK是低电平,说明空闲状态是低电平,CPOL=0;
第一个数据电平已经准备好了,第一个跳变沿就采集数据,CPHA=0;说明这个SPI通信是mode0模式。
SPI通信有时的固件中SPI读,通过发送dummy来完成:
dummy字节的发送,实际上是在SCK上发送一系列脉冲给从机,但是MOSI电平不变,MISO采集电平变化,并保存为数据。
由于SCK是由主机控制的,每次SPI通信也必须由主机控制SCK信号产生相应的脉冲,
所以很多固件中把读一个字节的数据写成send dummy,其实就是发送脉冲,不发送数据,接收数据的意思。
LCD5110,12864黑白液晶驱动。
首先,只要硬件上没错,肯定是可以调试出来的。不要一调不出来就变无头苍蝇。
一次成功最好了,如果没成功,第一件要做的事情就是用示波器观察SPI通信各引脚的电平,
可以写一个循环,先发送一个字节数据,再发送一个字节命令,不断重复,这样观察MOSI,SCK,DATA/COMMAND,EN,的电平,
并与数据手册上的时序图严格对照,确定SPI通讯正确。然后再回到固件中对照初始化程序每一条是否正确。
点阵液晶实现动画效果
下面主要说一下LCD5110,12864这类一个字节控制8个点,每次发送一个字节数据的液晶,实现动态画图的要点:
画图最重要的就是可以在任意一个坐标显示一个点,只要做到了这个,其他的都很容易了。
由于这类液晶驱动芯片内部的RAM只能一次更新8个点,要做到在任意一个坐标A,显示一个点,
只能通过发送8位数据到该点所对应RAM去,让这8位数据对应的其他位不变,而只把A坐标位置的点置1.
怎么做?很容易,比如A坐标对应第0位:
要显示A点,那么就让原先RAM中的一个字节byte|0x01;
要清除A点,就让原先RAM中的一个字节byte&0xfe;
可是这个byte怎么得到?有的芯片支持SPI读液晶驱动芯片的RAM,可以通过读取该点对应ram的一个字节来得到,
但这样每次更新一个点,要先读,再写,降低了更新速度。并且有的芯片不支持SPI读RAM。
这样的话,就要求我们有可以记录液晶各点状态的东西,
可以在内存中建立一个数组,对应要控制区域的RAM,每次要更新一个点,就通过|,&运算更新内存数组中的相应字节,然后SPI发送该字节到对应RAM。
TFT彩屏液晶驱动。
由于彩屏驱动要控制一个点显示什么颜色,每次向控制芯片RAM中,发送的是8位或者16位的颜色值,
画一个点传送一个或者两个字节,不会影响周围的点,所以不存在要建立内存数组的问题。
软件模拟的SPI通讯速度不够,驱动2.2寸TFT显示,刷新速度太慢,用硬件SPI让它工作在最高速度驱动彩屏TFT的刷新速度还可以接受。